package com.sojson.util.security.shiro.filter;

import java.io.IOException;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;

import com.sojson.config.exception.TransErrorCode;
import com.sojson.constant.ConstantByMap;
import com.sojson.util.filter.FilterUtil;
import com.sojson.util.servlet.ServletUtil;

/**
 * 判断是否拥有访问的权限
 * 
 * @author liu
 * @date 2020-11-02
 */
public class PermissionFilter extends PermissionsAuthorizationFilter {

    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
        throws IOException {
        System.out.println("过滤器:PermissionFilter:isAccessAllowed");

        String requestMapping = getRequestMapping((HttpServletRequest)request);// 获取URI

        // // 如果是相关目录return true
        // if (ShiroFilterUtils.isOpenUrl(httpRequest)) {
        // return Boolean.TRUE;
        // }

        Subject subject = getSubject(request, response);
        if (null != mappedValue) {
            String[] arra = (String[])mappedValue;
            for (String permission : arra) {
                if (subject.isPermitted(permission)) {
                    return Boolean.TRUE;
                }
            }
        }

        // /**
        // * 此处是改版后，为了兼容项目不需要部署到root下，也可以正常运行，但是权限没设置目前必须到root 的URI， 原因:如果你把这个项目叫
        // * ShiroDemo，那么路径就是 /ShiroDemo/xxxx.shtml
        // * ，那另外一个人使用，又叫Shiro_Demo,那么就要这么控制/Shiro_Demo/xxxx.shtml 理解了吗？
        // * 所以这里替换了一下，使用根目录开始的URI
        // */
        // String basePath = httpRequest.getContextPath();// 获取basePath
        // if (null != uri && uri.startsWith(basePath)) {
        // uri = uri.replaceFirst(basePath, "");
        // }
        if (subject.isPermitted(requestMapping)) {
            return Boolean.TRUE;
        }

        return Boolean.FALSE;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
        responseDateTouch(request, response, TransErrorCode.NOT_USER_PERMISSION,
            ConstantByMap.CONTROLLER_URL_OPEN_UNAUTHORIZED_URL_ALL);
        return Boolean.FALSE;
    }

    /**
     * 对结果进行处理并更新Session
     * 
     * @param request
     * @param response
     * @param code 错误代码
     * @param url 要跳转的路径
     * @throws IOException
     */
    private void responseDateTouch(ServletRequest request, ServletResponse response, TransErrorCode code, String url)
        throws IOException {
        FilterUtil.responseDateTouch(request, response, code, url);
    }

    /**
     * 获取客户端访问的地址
     * 
     * @param request
     * @return
     */
    private String getRequestMapping(HttpServletRequest request) {
        return ServletUtil.getRequestMapping(request);
    }

}